﻿#include "twidget.h"
#include "Graph.h"
#include <string>
#include <QRegularExpression>
#include <QTextStream>
#include <QPainter>
#include <QFile>

using namespace std;

Twidget::Twidget(QWidget *parent)
	: QWidget(parent)
{
    paintMode = 0;   //默认绘制欢迎页
    route = NULL;    //路径是边的数组
    edgeNum = 0;  //路径边的数目
    transNum = 0;  //换乘数
    length = 0;   //总路径长度
    string start = "";   //起点站
    footMiles = 0;
    spotsN = 1;
    currentCost = 0;
    currentLength = 0;
}

Twidget::~Twidget()
{
    delete[] route;
}

void Twidget::paintEvent(QPaintEvent* event)
{
    if (paintMode == 0) {
        QPainter painter(this);
        QPixmap image(":/Icon/image/welcome.png");
        QRect r(0, 0, this->width(), this->height());
        painter.drawPixmap(r, image);
        painter.end();
    }
    else if (paintMode == 1|| paintMode == 2) {
        drawRoute();
    }
}

void Twidget::drawRoute() {
    QPainter painter(this);
    painter.setPen(Qt::NoPen);
    painter.setBrush(Qt::white);
    painter.drawRect(QRect(0, 0, this->width(), this->height()));
    Graph g;
    int sign = -1; //控制正负  ,小于0代表线路向左延伸，大于0代表向右延伸
    int row = 10;  //横排最大数量
    int diameter = 60;  //直径
    int wlength = 30;   //同行圆间线长
    int linespace = 40;  //行间距
    int linewidth = 8;   //线宽
    int R = 0;
    int G = 0;
    int B = 0;

    int x = (this->width() - row * diameter - (row - 1) * wlength) / 2;
    int y = -70;

    int xR = 0;    //路径公里数显示位置的x坐标
    int xT = this->width() / 3;   //换乘数显示位置的x坐标
    int xP = this->width() * 2 / 3; //票价显示位置的x坐标
    int xS = this->width() / 2;   //游览景点数显示位置的x坐标
    int yT = this->height() - 15;  //文字显示位置的y坐标
    int xTT = 0;                   //旅游推荐文字显示位置的x坐标
    int yTT = this->height() - 35;  //旅游推荐文字显示位置的y坐标

    if (edgeNum == 0) {
        painter.setPen(QPen(Qt::black));
        painter.setFont(QFont("楷体", 15, QFont::Bold));
        painter.drawText(0,0,QString::fromStdString("起点站与终点站重合"));
        return;
    }

    for (int i = 0; i < edgeNum + 1; i++) {

        /*控制正负——延伸方向*/
        if (i % row == 0) {
            sign = -sign;
            y += (diameter + linespace);
        }
        else {
            x += (diameter + wlength) * sign;
        }

        /*设置圆内的填充颜色*/
        if (i == 0) {   //起点站设为红色
            QBrush brush(QColor(255, 0, 0), Qt::Dense4Pattern);
            painter.setBrush(brush);
        }
        else if (i == edgeNum) {   //终点设为绿色
            QBrush brush(QColor(0, 255, 0), Qt::Dense4Pattern);
            painter.setBrush(brush);
        }
        else if (route[i].line != route[i - 1].line) {  //换乘站设为黄色
            QBrush brush(QColor(255, 215, 0), Qt::Dense4Pattern);
            painter.setBrush(brush);
        }
        else {
            QBrush brush(QColor(30, 144, 255), Qt::Dense4Pattern);
            painter.setBrush(brush);
        }

        /*读取线路颜色*/
        if (i < edgeNum) {
            QFile colorL(":/files/files/colorL.txt");
            colorL.open(QIODevice::ReadOnly);
            QTextStream in(&colorL);
            while (true) {
                QString array = in.readLine();
                array = array.trimmed();
                if (array.isNull()) {
                    break;
                }
                QStringList parts = array.split(",");   //按","分割
                if (parts.at(0).toInt() == route[i].line) {
                    R = parts.at(1).toInt();
                    G = parts.at(2).toInt();
                    B = parts.at(3).toInt();
                    break;
                }
            }
        }

        /*设置圆的颜色和画圆*/
        painter.setPen(QPen(QColor(0, 0, 128), 2, Qt::SolidLine, Qt::RoundCap));
        painter.drawEllipse(x, y, diameter, diameter);

        /*画站点间的连线*/
        if (i % row == row - 1 && i < edgeNum) {      //上拐点，线路向下延伸
            painter.setPen(QPen(QColor(R, G, B), linewidth, Qt::SolidLine, Qt::RoundCap));
            painter.drawLine(QLine(x + diameter / 2, y + diameter, x + diameter / 2, y + (diameter + linespace)));
        }
        else if (sign > 0 && i < edgeNum) {     //向右延伸
            painter.setPen(QPen(QColor(R, G, B), linewidth, Qt::SolidLine, Qt::RoundCap));
            painter.drawLine(QLine(x + diameter, y + diameter / 2, x + (diameter + wlength), y + diameter / 2));
        }
        else if (sign < 0 && i < edgeNum) {
            painter.setPen(QPen(QColor(R, G, B), linewidth, Qt::SolidLine, Qt::RoundCap));
            painter.drawLine(QLine(x - wlength, y + diameter / 2, x, y + diameter / 2));
        }

        /*显示站点名称*/
        if (i < edgeNum) {
            painter.setPen(QPen(Qt::black));
            painter.setFont(QFont("宋体", 12, QFont::Bold));
            painter.drawText(x, y + 40, QString::fromStdString(g.getStationName(route[i].from)));
        }
        else if (i == edgeNum && i != 0) {
            painter.setPen(QPen(Qt::black));
            painter.setFont(QFont("宋体", 12, QFont::Bold));
            painter.drawText(x, y + 40, QString::fromStdString(g.getStationName(route[edgeNum - 1].to)));
        }
        else if (i == 0) {
            painter.setPen(QPen(Qt::black));
            painter.setFont(QFont("宋体", 12, QFont::Bold));
            painter.drawText(x, y + 40, QString::fromStdString(start));
        }
    }
    /*显示路径里程、换乘数、票价*/
    string origP = to_string(currentCost);
    string cheapP = to_string(currentCost * calSale());
    painter.setPen(QPen(Qt::black));
    painter.setFont(QFont("楷体", 15, QFont::Bold));
    painter.drawText(xR, yT, QString::fromStdString("该出行方案总里程：" + to_string(length) + "米"));
    painter.drawText(xT, yT, QString::fromStdString("换乘数：" + to_string(transNum) + "次"));
    painter.drawText(xTT, yTT, QString::fromStdString("为您推荐站点：" + g.getStationName(route[edgeNum - 1].to) + "  该站点距 " + spot + " 步行距离为" + to_string(footMiles) + "米"));
    painter.drawText(xP, yT, QString::fromStdString("优惠价：" + cheapP.substr(0, cheapP.find(".") + 1 + 1) + "元（原价：" + origP.substr(0, origP.find(".") + 1 + 1) + "）"));
    painter.drawText(xS, yT, QString::fromStdString("景点站数：" + to_string(spotsN) + "个"));

    painter.end();
}

void Twidget::setAttr(Edge* r, int EdgeN, int TransN, int l,int footmiles,std::string s, std::string sp) {
    if (paintMode != 2) {//不在“游览多景点规划”状态
        delete[] route;
        route = new Edge[EdgeN];
        for (int i = 0; i < EdgeN; i++) {
            route[i] = r[i];
        }
        edgeNum = EdgeN;
        transNum = TransN;
        length = l;
        currentLength = l;
        footMiles = footmiles;
        start = s;
        spot = sp;
        calcost(length);
    }
    else if(paintMode==2)    //在“游览多景点规划”状态，在原来的边集上追加
    {
        if (EdgeN == 0) {
            spot = sp;
            return;
        }
        //edgeNum += EdgeN;
        Edge* tempEdge = new Edge[edgeNum+EdgeN];
        for (int i = 0; i < edgeNum + EdgeN; i++) {
            if (i < edgeNum) {
                tempEdge[i] = route[i];
            }
            else {
                tempEdge[i] = r[i - edgeNum];
            }
        }
        delete[] route;
        edgeNum += EdgeN;
        route = tempEdge;   
        transNum += TransN;   //换乘数追加
        length += l;    //路径长度追加
        currentLength = l; //当前路径长度更新
        footMiles = footmiles;
        //start = s;   //起点不更新
        spot = sp;
        spotsN++;
        calcost(currentLength);
    }
    
}

void Twidget:: calcost(int len) {
    int cost = 0;  //价格
    int upLimit = 0;  //目前最高价格——当价格进入“每增加XX公里，增收XX元”范围内时使用
    int lenLimit = 0;//目前最高里程——当价格进入“每增加XX公里，增收XX元”范围内时使用
    QFile priceT(":/files/files/ticketPrice.txt");
    priceT.open(QIODevice::ReadOnly);
    QTextStream readP(&priceT);
    QRegularExpression sepatator("-|,");//以-和,分割
    for (int j = 0;; j++)
    {
        QString infoP = readP.readLine();
        infoP = infoP.trimmed();
        if (infoP.isNull()) {
            break;
        }
        if (j != 0) {   //表头不读
            if (infoP.at(0).toLatin1() != '/') {    //不是按“每增加XX公里，增收XX元”规律递增
                QStringList partsP = infoP.split(sepatator);
                upLimit = partsP.at(2).toInt();    //记录当前最高价格
                lenLimit = partsP.at(1).toInt();   //记录当前最高里程
                if (len / 1000 >= partsP.at(0).toInt() && len / 1000 < partsP.at(1).toInt()) {
                    cost = partsP.at(2).toInt();
                    break;
                }
            }
            else if (len / 1000 >= lenLimit) {
                QStringList partsP2 = infoP.split(",");
                QString perKM(partsP2.at(0));
                QString add(partsP2.at(1));
                perKM.remove('/');
                add.remove('+');
                int everyKM = perKM.toInt();
                int delta = add.toInt();
                int spend = ceil(((float)len / 1000 - lenLimit) / everyKM) * delta + upLimit;
                cost = spend;
                break;
            }
        }
        if (len == 0) {
            cost = 0;
            break;
        }
    }
    priceT.close();
    if (paintMode != 2) {
        currentCost = cost;
    }
    else {
        currentCost += cost;
    }
}

int Twidget::getPaintMode() const {
    return paintMode;
}

int Twidget::getEdgeNum()const {
    return edgeNum;
}

Edge* Twidget::getEdge() {
    return route;
}

void Twidget::setPaintMode(int i) {
    paintMode = i;
}

void Twidget::setSpotNum(int num) {
    spotsN = num;
}

void Twidget::spotsPlus() {
    spotsN++;
}

float Twidget::calSale() {
    if (spotsN <= 1) {
        return 1;
    }
    float discount = 0;
    QFile Tticket(":/files/files/sale.txt");
    Tticket.open(QIODevice::ReadOnly);
    QTextStream readP(&Tticket);
    for (int j = 0;; j++)
    {
        QString infoP = readP.readLine();
        infoP = infoP.trimmed();
        if (infoP.isNull()) {
            break;
        }
        if (j != 0) {   //表头不读
            if (infoP.at(0).toLatin1() != '>') {    //不是最后一行
                QStringList partsP = infoP.split(",");
                if (spotsN == partsP.at(0).toInt()) {
                    QString discountT(partsP.at(1));
                    discount = discountT.toFloat();
                    break;
                }
            }
            else if (infoP.at(0).toLatin1() == '>') {
                QStringList partsP = infoP.split(",");
                QString discountT(partsP.at(1));
                discount = discountT.toFloat();
                break;
            }
        }
    }
    Tticket.close();
    return discount;
}

void Twidget::clearEdge() {
    delete[] route;
    edgeNum = 0;
    route = NULL;
    update();
}

void Twidget::clearAccuCost() {
    currentCost = 0;
}

void Twidget::clearLength() {
    length = 0;
}

void Twidget::clearTrans() {
    transNum = 0;
}